/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 *
 * $Id: IOServer.cpp,v 1.9 2009-05-13 07:18:17 amaula Exp $
 *
 * \file
 * \brief MaCI - Implementation of IO Server interface
 * \author Matthieu Myrsky <matthieu.myrsky@tkk.fi>
 */
#include "IOServer.hpp"
//*****************************************************************************
#define GIMI_CLIENT_API (20000)
#include "gimi.h"
//*****************************************************************************
//*****************************************************************************
using namespace MaCI::IO;
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************


CIOServer::CIOServer(MaCICtrl::CMaCICtrlServer *aMaCICtrlServerPtr, const int aInterfaceMinor)
  : CMaCI(aMaCICtrlServerPtr, GIMI_PROTOCOL_MACI_IO, aInterfaceMinor),
    iServerActive(false),
    iIODataArray()
{


}
//*****************************************************************************

CIOServer::~CIOServer()
{
  Close();
}
//*****************************************************************************

MaCI::EMaCIError CIOServer::DoOpen(void)
{
  EMaCIError result = KMaCIError;
  assert(this != NULL);
  assert(iGIMIPtr != NULL);

  if(!iServerActive){
    RegisterProvidedService("MaCI - IO Interface");
    RegisterAcceptedService("MaCI - IO CommandInterface");
    iServerActive = true;
    //CThread::RunThread();
    result = KMaCIOK;
  }else{
    dPrint(3, "Server already opened");

  }
  return result;
}
//*****************************************************************************

MaCI::EMaCIError CIOServer::DoClose(void)
{
 EMaCIError result = KMaCIError;
 assert(this != NULL);
 assert(iGIMIPtr != NULL);
 if (iServerActive) {
   // Unregister services
    UnregisterProvidedService();
    UnregisterAcceptedService();
   // Stop the handler Thread
   iServerActive = false;
   ///* CThread::CancelThread(); //Removed by script */
   //CThread::WaitThread();
 }
 return result;
}
//*****************************************************************************

MaCI::EMaCIError CIOServer::SendReply(CIOData &aData,
				      TReplyInfo &aInfo)
{

  aData.Print(10);
  EMaCIError result = KMaCIError;
  if(iServerActive){
    gim::binbag::CBinBag replybb;
    // Do encoding to this binbag
    //    aData.EncodeTo(&replybb);
  
    int r = iGIMIPtr->send(aInfo.senderId,
			   aData.GetBinBagContainerPtr()->GetBuffer(),
			   aData.GetBinBagContainerPtr()->GetBufferSize(),
			   iInterfaceMajor,
			   iInterfaceMinor,
			   aInfo.msgId);
    
    if (r == GIMI_OK) {
      dPrint(8,"Succesfully sent message with %d BinBag elements to '%p'",
	     replybb.GetElementCount(),
	     aInfo.senderId);

      result = KMaCIOK;
      
    } else {
      
      dPrint(5,"Failed to send message with %d BinBag elements to '%p'",
	     replybb.GetElementCount(),
	     aInfo.senderId);
    }
  }else{
    result = KMaCINoConnection;
    
  }

  return result;

}
//*****************************************************************************

MaCI::EMaCIError CIOServer::WaitCommand(CIOData &aData, 
					TReplyInfo &aInfo,
					const unsigned int aTimeout_ms)
{
  EMaCIError result= KMaCIError;
  if(iServerActive){
   
    gimi::GIMIMessage gmsg;
    
    bool r;
    gim::binbag::CBinBag bb;
    CIOData data;
    result = ReceiveInterfaceMessage(gmsg, aTimeout_ms);
    
    if (result == KMaCIOK) {
      dPrint(8,"Got GIMIMessage %d - Processing.", gmsg.messageId);
      //Decode message
      r = bb.Decode(gmsg.getData(), gmsg.getDatalength());
      if(r){
	// Succesfully decoded as BinBag.
	r = data.DecodeFrom(&bb);
	if (r) {
	  const TCommand *cmd = data.GetCommand();
	  if (cmd) {
            aData = data;
	    switch(cmd->cmd) {
	      // Default action for Set commands is to set TReplyInfo
	    case KCommandGetDigitalPin:
	    case KCommandGetDigitalBlock :
	    case KCommandGetAnalogVoltage:
	      
	      aInfo.senderId=gmsg.getSenderId();
	      aInfo.msgId=gmsg.messageId;
	      
	      break;
	    }
	  }
	}else{
        
	  result = KMaCIError;
	}
      }else{
        
	result = KMaCIError;
      }
    }
  }else{

    result = KMaCINoConnection;

  }

  return result;
}
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************


